''' -----------------------------------------------------------------------------
''' Project	 : Alpha3D
''' Class	 : MyDevice
''' 
''' -----------------------------------------------------------------------------
''' <summary>
''' Main graphics class.
''' </summary>
''' <history>
''' 	[Cime]	7.8.2005	Created
''' </history>
''' -----------------------------------------------------------------------------
Public Class MyDevice
    Implements IDisposable

    'VARIABLES
    Private g_Dev As Device
    Private g_PresentParameters As New PresentParameters
    Private g_ClearFlags As ClearFlags
    Private cTarget As Control
    Private bWindowed As Boolean


#Region " Clear Methods ... "
    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    Public Sub Clear()
        Me.g_Dev.Clear(Me.g_ClearFlags, Color.Black, 1, 0)
    End Sub

    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    Public Sub Clear(ByVal Color As Color)
        Me.g_Dev.Clear(Me.g_ClearFlags, Color, 1, 0)
    End Sub

    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    Public Sub Clear(ByVal Color As Integer)
        Me.g_Dev.Clear(Me.g_ClearFlags, Color, 1, 0)
    End Sub

    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub Clear(ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.g_Dev.Clear(Me.g_ClearFlags, Color.Black, ZDepth, Stencil)
    End Sub

    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub Clear(ByVal Color As Color, ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.g_Dev.Clear(Me.g_ClearFlags, Color, ZDepth, Stencil)
    End Sub

    ''' <summary>
    ''' Clears the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub Clear(ByVal Color As Integer, ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.g_Dev.Clear(Me.g_ClearFlags, Color, ZDepth, Stencil)
    End Sub
#End Region

#Region " BeginScene overloads ... "
    ''' <summary>
    ''' Begins the scene.
    ''' </summary>
    Public Sub BeginScene(Optional ByVal DoClear As Boolean = True)
        If DoClear Then Me.Clear()
        Me.g_Dev.BeginScene()
    End Sub

    ''' <summary>
    ''' Clears the scene then begins the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    Public Sub BeginScene(ByVal Color As Color)
        Me.Clear(Color)
        Me.g_Dev.BeginScene()
    End Sub

    ''' <summary>
    ''' Clears the scene then begins the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    Public Sub BeginScene(ByVal Color As Integer)
        Me.Clear(Color)
        Me.g_Dev.BeginScene()
    End Sub

    ''' <summary>
    ''' Clears the scene then begins the scene.
    ''' </summary>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub BeginScene(ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.Clear(ZDepth, Stencil)
        Me.g_Dev.BeginScene()
    End Sub

    ''' <summary>
    ''' Clears the scene then begins the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub BeginScene(ByVal Color As Color, ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.Clear(Color, ZDepth, Stencil)
        Me.g_Dev.BeginScene()
    End Sub

    ''' <summary>
    ''' Clears the scene then begins the scene.
    ''' </summary>
    ''' <param name="Color">The color to use to clear the scene.</param>
    ''' <param name="ZDepth">New z value that this method stores in the depth buffer. This parameter can be in the range of 0.0 through 1.0 (for z-based or w-based depth buffers). A value of 0.0 represents the nearest distance to the viewer; a value of 1.0 represents the farthest distance.</param>
    ''' <param name="Stencil">Integer value to store in each stencil-buffer entry. This parameter can be in the range of 0 through 2n-1, where n is the bit depth of the stencil buffer.</param>
    Public Sub BeginScene(ByVal Color As Integer, ByVal ZDepth As Single, ByVal Stencil As Integer)
        Me.Clear(Color, ZDepth, Stencil)
        Me.g_Dev.BeginScene()
    End Sub
#End Region

#Region " End Scene Overload ... "
    ''' <summary>
    ''' Ends the scene.
    ''' </summary>
    Public Sub EndScene(Optional ByVal DoPresent As Boolean = True)
        Me.g_Dev.EndScene()
        If DoPresent Then Me.g_Dev.Present()
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub EndScene(ByVal RectPresent As Rectangle, ByVal OverrideWindowHandle As IntPtr, ByVal SourceRectangle As Boolean)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(RectPresent, OverrideWindowHandle, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    Public Sub EndScene(ByVal OverrideWindowHandle As IntPtr)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(OverrideWindowHandle)
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="SourceRectangle">A Rectangle  that contains the source rectangle. If the rectangle exceeds the source surface, it is clipped to the source surface. This parameter can be used only if the swap chain was created with SwapEffect.Copy.</param>
    ''' <param name="DestRectangle">A Rectangle  that contains the destination rectangle. This parameter can be used only if the swap chain was created with SwapEffect.Copy.</param>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    Public Sub EndScene(ByVal SourceRectangle As Rectangle, ByVal DestRectangle As Rectangle, ByVal OverrideWindowHandle As IntPtr)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(SourceRectangle, DestRectangle, OverrideWindowHandle)
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub EndScene(ByVal RectPresent As Rectangle, ByVal SourceRectangle As Boolean)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(RectPresent, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="OverrideWindow">Pointer to a destination window whose client area is taken as the target for this presentation. If this parameter is omitted, PresentParameters.DeviceWindow is taken.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub EndScene(ByVal RectPresent As Rectangle, ByVal OverrideWindow As Control, ByVal SourceRectangle As Boolean)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(RectPresent, OverrideWindow, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Ends the scene and calls present.
    ''' </summary>
    ''' <param name="OverrideWindow">Pointer to a destination window whose client area is taken as the target for this presentation. If this parameter is omitted, PresentParameters.DeviceWindow is taken.</param>
    Public Sub EndScene(ByVal OverrideWindow As Control)
        Me.g_Dev.EndScene()
        Me.g_Dev.Present(OverrideWindow)
    End Sub
#End Region

#Region " Present overloads ... "
    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    Public Sub Present()
        Me.g_Dev.Present()
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub Present(ByVal RectPresent As Rectangle, ByVal OverrideWindowHandle As IntPtr, ByVal SourceRectangle As Boolean)
        Me.g_Dev.Present(RectPresent, OverrideWindowHandle, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    Public Sub Present(ByVal OverrideWindowHandle As IntPtr)
        Me.g_Dev.Present(OverrideWindowHandle)
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="SourceRectangle">A Rectangle  that contains the source rectangle. If the rectangle exceeds the source surface, it is clipped to the source surface. This parameter can be used only if the swap chain was created with SwapEffect.Copy.</param>
    ''' <param name="DestRectangle">A Rectangle  that contains the destination rectangle. This parameter can be used only if the swap chain was created with SwapEffect.Copy.</param>
    ''' <param name="OverrideWindowHandle">Destination window whose client area is taken as the target for this presentation. If this parameter is not used, PresentParameters.DeviceWindow is taken.</param>
    Public Sub Present(ByVal SourceRectangle As Rectangle, ByVal DestRectangle As Rectangle, ByVal OverrideWindowHandle As IntPtr)
        Me.g_Dev.Present(SourceRectangle, DestRectangle, OverrideWindowHandle)
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub Present(ByVal RectPresent As Rectangle, ByVal SourceRectangle As Boolean)
        Me.g_Dev.Present(RectPresent, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="RectPresent">The Rectangle  to present.</param>
    ''' <param name="OverrideWindow">Pointer to a destination window whose client area is taken as the target for this presentation. If this parameter is omitted, PresentParameters.DeviceWindow is taken.</param>
    ''' <param name="SourceRectangle">Value that is set to true if a Rectangle  is being passed to the rectPresent parameter.</param>
    Public Sub Present(ByVal RectPresent As Rectangle, ByVal OverrideWindow As Control, ByVal SourceRectangle As Boolean)
        Me.g_Dev.Present(RectPresent, OverrideWindow, SourceRectangle)
    End Sub

    ''' <summary>
    ''' Presents the scene.
    ''' </summary>
    ''' <param name="OverrideWindow">Pointer to a destination window whose client area is taken as the target for this presentation. If this parameter is omitted, PresentParameters.DeviceWindow is taken.</param>
    Public Sub Present(ByVal OverrideWindow As Control)
        Me.g_Dev.Present(OverrideWindow)
    End Sub
#End Region

#Region " Constructors ... "
    Public Sub New()
    End Sub

    ''' <summary>
    ''' Sets fullscreen mode.
    ''' </summary>
    ''' <param name="Target">Reference to the control that the DX9Graphics class will render to.</param>
    ''' <param name="Width">The width of the display mode to use.</param>
    ''' <param name="Height">The height of the display mode to use.</param>
    Public Sub SetFullscreenMode(ByVal Target As Control, Optional ByVal Width As Integer = 1024, Optional ByVal Height As Integer = 768)
        Dim objAdapters As Direct3D.AdapterInformation
        Dim DevCaps As Direct3D.Caps
        Dim DevFlags As Direct3D.CreateFlags
        Dim DevType As Direct3D.DeviceType = DeviceType.Hardware

        ' get adapter info for specified adapter
        objAdapters = Direct3D.Manager.Adapters(0)

        Try
            Me.PresentParameters.Windowed = False
            Me.g_PresentParameters.BackBufferWidth = Width
            Me.g_PresentParameters.BackBufferHeight = Height
            Me.g_PresentParameters.BackBufferCount = 1
            Me.g_PresentParameters.SwapEffect = SwapEffect.Copy
            Me.g_PresentParameters.PresentationInterval = PresentInterval.Immediate
            Me.g_PresentParameters.BackBufferFormat = objAdapters.CurrentDisplayMode.Format
            Me.g_PresentParameters.FullScreenRefreshRateInHz = objAdapters.CurrentDisplayMode.RefreshRate

            Init(Target)

        Catch err As Exception
            Throw New A3DException("Could not initialize graphics.", err)
        End Try
    End Sub

    ''' <summary>
    ''' Sets windowed mode.
    ''' </summary>
    ''' <param name="Target">Reference to the control that the DX9Graphics class will render to.</param>
    Public Sub SetWindowedMode(ByVal Target As Control)
        Dim objAdapters As Direct3D.AdapterInformation
        Dim DevCaps As Direct3D.Caps
        Dim DevFlags As Direct3D.CreateFlags
        Dim DevType As Direct3D.DeviceType = DeviceType.Hardware

        ' get adapter info for specified adapter
        objAdapters = Direct3D.Manager.Adapters(0)

        Try
            Me.PresentParameters.Windowed = True
            Me.g_PresentParameters.BackBufferWidth = Target.Width
            Me.g_PresentParameters.BackBufferHeight = Target.Height
            Me.g_PresentParameters.BackBufferCount = 1
            Me.g_PresentParameters.SwapEffect = SwapEffect.Copy
            Me.g_PresentParameters.PresentationInterval = PresentInterval.Immediate
            Me.g_PresentParameters.BackBufferFormat = objAdapters.CurrentDisplayMode.Format

            Init(Target)

        Catch err As Exception
            Throw New A3DException("Could not initialize graphics.", err)
        End Try
    End Sub

    ''' <summary>
    ''' Sets custom mode.
    ''' </summary>
    ''' <param name="PresentParameters">Reference to the present parameters.</param>
    Public Sub SetCustomMode(ByVal Target As Control, ByVal PresentParameters As PresentParameters)
        Try
            Me.g_PresentParameters = PresentParameters
            Init(Target)
        Catch err As Exception
            Throw New A3DException("Could not initialize graphics.", err)
        End Try
    End Sub

    Public Sub Init(ByVal Target As Control)

        Dim objAdapters As Direct3D.AdapterInformation
        Dim DevCaps As Direct3D.Caps
        Dim DevFlags As Direct3D.CreateFlags
        Dim DevType As Direct3D.DeviceType = DeviceType.Hardware


        ' get adapter info for specified adapter
        objAdapters = Direct3D.Manager.Adapters(0)


        ' start device check loop  
RetryDeviceTypeCheck:
        'check if device can be created with the specied formats
        If Not Direct3D.Manager.CheckDeviceType(0, DevType, objAdapters.CurrentDisplayMode.Format, Me.g_PresentParameters.BackBufferFormat, Me.g_PresentParameters.Windowed) Then
            Select Case DevType
                Case DeviceType.Hardware
                    ' it could not create device so try again with software
                    DevType = DeviceType.Software


                    GoTo RetryDeviceTypeCheck

                Case DeviceType.Software
                    ' failed again with software so raise exception

                    Dim Msg As String
                    Msg = "CheckDeviceType returned False for Hardware and software using the fallowing parameters ..."
                    Msg &= vbCrLf & "---------------------------------"
                    Msg &= vbCrLf & "CurrentDisplayMode.Format: " & objAdapters.CurrentDisplayMode.Format.ToString
                    Msg &= vbCrLf & "BackBufferFormat: " & Me.g_PresentParameters.BackBufferFormat.ToString
                    Msg &= vbCrLf & "Windowed: " & CBool(Me.g_PresentParameters.Windowed).ToString
                    Throw New A3DException(Msg)
            End Select
        End If

        'specify depth buffer
        If Manager.CheckDepthStencilMatch(0, DevType, Me.g_PresentParameters.BackBufferFormat, Me.g_PresentParameters.BackBufferFormat, Direct3D.DepthFormat.D16) Then
            'support exists.
            Me.g_PresentParameters.AutoDepthStencilFormat = Direct3D.DepthFormat.D16
            Me.g_PresentParameters.EnableAutoDepthStencil = True
        Else
            'support does not exist!
            Throw New A3DException("Direct3D Adapter does not support 16bit depth buffers.")
        End If

        ' check device capabilities
        DevCaps = Manager.GetDeviceCaps(0, DevType)


        ' take advantage of hw tnl where available
        If DevCaps.DeviceCaps.SupportsHardwareTransformAndLight Then
            If DevCaps.DeviceCaps.SupportsPureDevice Then
                DevFlags = Direct3D.CreateFlags.HardwareVertexProcessing Or Direct3D.CreateFlags.PureDevice
            Else
                DevFlags = Direct3D.CreateFlags.HardwareVertexProcessing
            End If
        Else
            DevFlags = Direct3D.CreateFlags.MixedVertexProcessing
        End If

        Me.g_PresentParameters.PresentationInterval = PresentInterval.Immediate

        Me.g_Dev = New Device(0, DeviceType.Hardware, Target, CreateFlags.HardwareVertexProcessing, Me.g_PresentParameters)

        If Me.g_Dev Is Nothing Then
            DevType = DeviceType.Software
            Me.g_Dev = New Direct3D.Device(objAdapters.Adapter, DevType, Target, DevFlags, Me.g_PresentParameters)
        End If

        If Me.g_Dev Is Nothing Then Throw New A3DException("Cound not create hardware or software device.")


        Me.g_ClearFlags = Direct3D.ClearFlags.Target Or Direct3D.ClearFlags.ZBuffer

        ' setup device
        Me.g_Dev.RenderState.ZBufferEnable = True
        Me.g_Dev.RenderState.Lighting = False
        Me.g_Dev.RenderState.AlphaBlendEnable = True
        Me.g_Dev.RenderState.SourceBlend = Direct3D.Blend.SourceAlpha
        Me.g_Dev.RenderState.DestinationBlend = Direct3D.Blend.InvSourceAlpha
        Me.g_Dev.RenderState.CullMode = Cull.None
        Me.g_Dev.SamplerState(0).MinFilter = Direct3D.TextureFilter.Linear
        Me.g_Dev.SamplerState(0).MagFilter = Direct3D.TextureFilter.Linear
        Me.g_Dev.RenderState.Ambient = Color.FromArgb(128, 128, 128)
    End Sub

#End Region

#Region " Other device overloads ... "
    Public Sub SetTexture(ByVal stage As Integer, ByVal texture As Texture)
        Me.g_Dev.SetTexture(stage, texture)
    End Sub

    Public Sub SetTransform(ByVal state As TransformType, ByVal matrix As Matrix)
        Me.g_Dev.SetTransform(state, matrix)
    End Sub

    Public Sub Fog(ByVal Enable As Boolean, ByVal Color As Color, ByVal Mode As FogMode, Optional ByVal Density As Single = 1, Optional ByVal Start As Single = 0, Optional ByVal [End] As Single = 100)
        With Me.g_Dev.RenderState
            .FogEnable = Enable
            .FogColor = Color
            .FogTableMode = Mode
            .FogDensity = Density
            .FogStart = Start
            .FogEnd = [End]
        End With
    End Sub


    Public ReadOnly Property Lights() As LightsCollection
        Get
            Return Me.g_Dev.Lights
        End Get
    End Property

    Public Property Material() As Material
        Get
            Return Me.g_Dev.Material
        End Get
        Set(ByVal Value As Material)
            Me.g_Dev.Material = Value
        End Set
    End Property

    Public Property Viewport() As Viewport
        Get
            Return Me.g_Dev.Viewport
        End Get
        Set(ByVal value As Viewport)
            Me.g_Dev.Viewport = Me.Viewport
        End Set
    End Property
#End Region

    ''' <summary>
    ''' Provides access to the default clear flags.
    ''' </summary>
    ''' <returns>Returns a Direct3D.ClearFlags type.</returns>
    Public Property ClearFlags() As Direct3D.ClearFlags
        Get
            Return Me.g_ClearFlags
        End Get
        Set(ByVal Value As Direct3D.ClearFlags)
            Me.g_ClearFlags = Value
        End Set
    End Property

    ''' <summary>
    ''' Provides access to the PresentParameters.
    ''' </summary>
    ''' <returns>Returns a refrence to a Direct3D.PresentParameters type stored internally.</returns>
    Public Property PresentParameters() As Direct3D.PresentParameters
        Get
            Return Me.g_PresentParameters
        End Get
        Set(ByVal Value As Direct3D.PresentParameters)
            Try
                Me.g_PresentParameters = Value
            Catch ex As Exception
                Throw New A3DException(ex.Message, ex.InnerException)
            End Try
        End Set
    End Property

    ''' <summary>
    ''' Provides a reference to the Direct3D.Device type stored internally.
    ''' </summary>
    ''' <returns>Returns a reference to the Direct3D.Device type stored internally.</returns>
    Public ReadOnly Property Device() As Device
        Get
            Return Me.g_Dev
        End Get
    End Property

#Region " Dispose ... "
    Protected Overrides Sub Finalize()
        MyBase.Finalize()
        Me.Dispose()
    End Sub

    Public Sub Dispose() Implements System.IDisposable.Dispose
        If Not Me.g_Dev Is Nothing Then
            Me.g_Dev.Dispose()
            Me.g_Dev = Nothing
            Me.g_PresentParameters = Nothing
        End If
    End Sub
#End Region

End Class
